﻿using Microsoft.AspNetCore.Mvc;
using MyDapperApi.Services;
using QYWXUpdate.DataModel.QYWXCallBack;
using QYWXUpdate.DataModel.QYWXDocument;
using System.Collections;
using System.Net;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace MyDapperApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class QYWXReceiveController : ControllerBase
{
    private readonly IAutoNetUpdateService _autoNetUpdateService;
    private readonly IDateBaseService _dateBaseService;
    private readonly INetDocumentService _netDocumentService;
    private readonly IQywxCallBackService _qywxCallBackService;

    //企业微信后台开发者设置的token, corpID, EncodingAESKey
    private readonly string sToken = "NO3Ma17gJk";//企业微信后台，开发者设置的Token
    private readonly string sCorpID = "ww41ce2a97523f4d1a";//企业号corpid是企业号的专属编号（CorpID）[不同场景含义不同，详见文档说明（ToUserName：企业微信的CorpID，当为第三方应用回调事件时，CorpID的内容为suiteid）]
    private readonly string sEncodingAESKey = "lhxbMEwEVPMADwKcC1jpiCSzF7yNkCqiEHwSclqBb0s";//企业微信后台，开发者设置的EncodingAESKey

    public QYWXReceiveController(IAutoNetUpdateService autoNetUpdateService, IDateBaseService dateBaseService, INetDocumentService netDocumentService, IQywxCallBackService qywxCallBackService)
    {
        _autoNetUpdateService = autoNetUpdateService;
        _dateBaseService = dateBaseService;
        _netDocumentService = netDocumentService;
        _qywxCallBackService = qywxCallBackService;
    }

    [HttpPost("EncryptedTestMsg")]
    public ActionResult EncryptedTestMsg()
    {
        try
        {
            // 1. 生成时间戳和随机数（模拟企业微信的请求参数）
            //string timestamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
            string timestamp = "1761025974";
            //string nonce = Guid.NewGuid().ToString().Substring(0, 10); // 随机字符串
            string nonce = "qrsyfr6c22r"; // 随机字符串

            // 2. 使用现有WXBizMsgCrypt类进行加密
            WXBizMsgCrypt crypt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
            string encryptedMsg = "";
            int result = crypt.EncryptMsg(Request.Body.ToString(), timestamp, nonce, ref encryptedMsg);

            if (result == 0)
            {
                // 加密成功，返回包含加密信息的XML（可直接作为POST请求体）
                return Content(encryptedMsg);
            }
            else
            {
                throw new Exception($"加密失败，错误码：{result}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"生成加密消息失败：{ex.Message}");
            return null;
        }
    }

    [HttpGet("CallBack")]
    public async Task<ActionResult> CallBackGet([FromQuery] QywxVerifyRequest request)
    {
        var users = await _qywxCallBackService.CallBackGet(request);

        var res = string.Empty;

        res = users.data.ToString();

        return Content(res);//重新编译
    }

    [HttpPost("CallBack")]
    public async Task<IActionResult> CallBackPost([FromQuery] QewxReceiveRequest request)
    {
        string xmlContent;
        using (var reader = new StreamReader(Request.Body))
        {
            xmlContent = await reader.ReadToEndAsync();
        }

        _dateBaseService.CreateLog("CallBack", request.msg_signature +" "+ request.nonce + " "+ request.timestamp, xmlContent, 1);

        string responseContent = "响应失败，未获取到xml中的请求参数";
        if (!string.IsNullOrEmpty(xmlContent))
        {
            //指令响应回调
            responseContent = CommandCallback(request, xmlContent);
        }

        return Content(responseContent);
    }

    //[HttpPost("CallBack")]
    //public async Task<IActionResult> CallBackPost([FromQuery] QewxReceiveRequest request)
    //{
    //    string xmlContent;
    //    using (var reader = new StreamReader(Request.Body))
    //    {
    //        xmlContent = await reader.ReadToEndAsync();
    //    }

    //    string responseContent = "响应失败，未获取到xml中的请求参数";
    //    if (!string.IsNullOrEmpty(xmlContent))
    //    {
    //        var str = request.msg_signature + " " + request.nonce + " " + request.timestamp;
    //        _dateBaseService.CreateLog("CallBack", str, xmlContent, 1);
    //    }

    //    return Content("success");
    //}

    /// <summary>
    /// 指令响应回调
    /// </summary>
    /// <param name="Request"></param>
    /// <param name="postString">post请求的xml参数</param>
    /// <returns></returns>
    private string CommandCallback(QewxReceiveRequest Request, string postString)
    {
        string signature = Request.msg_signature;//微信加密签名，msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
        string timestamp = Request.timestamp;//时间戳
        string nonce = Request.nonce;//随机数                             
        var xmlDoc = XDocument.Parse(postString);//xml数据转化

        try
        {
            //https://work.weixin.qq.com/api/doc/90001/90143/90613
            //在发生授权、通讯录变更、ticket变化等事件时，企业微信服务器会向应用的“指令回调URL”推送相应的事件消息。
            //消息结构体将使用创建应用时的EncodingAESKey进行加密（特别注意, 在第三方回调事件中使用加解密算法，receiveid的内容为suiteid），请参考接收消息解析数据包。 本章节的回调事件，服务商在收到推送后都必须直接返回字符串 “success”，若返回值不是 “success”，企业微信会把返回内容当作错误信息。
            if (xmlDoc.Root.Element("Encrypt") != null)
            {
                //将post请求的数据进行xml解析，并将<Encrypt> 标签的内容进行解密，解密出来的明文即是用户回复消息的明文
                //接收并读取POST过来的XML文件流
                string decryptionParame = null;  // 解析之后的明文

                // 注意注意:sCorpID
                // @param sReceiveId: 不同场景含义不同，详见文档说明（[消息加密时为 CorpId]ToUserName：企业微信的CorpID，当为第三方应用回调事件时，CorpID的内容为suiteid）

                WXBizMsgCrypt crypt = new WXBizMsgCrypt(sToken, sEncodingAESKey, xmlDoc.Root.Element("ToUserName").Value);
                var result = crypt.DecryptMsg(signature, timestamp, nonce, postString, ref decryptionParame);

                if (result != 0)
                {
                    return "fial";
                }

                //响应应答处理
                return _qywxCallBackService.ReceiveResponse(decryptionParame, timestamp, signature, sToken, sEncodingAESKey, sCorpID).Result;
            }
        }
        catch (Exception ex)
        {
            //LoggerHelper._.Debug("异常：" + ex.Message);
        }

        return "fail";
    }
    /// <summary>
    /// 生成加密的回调消息（用于本地调试）
    /// </summary>
    /// <param name="rawXml">原始XML明文（如你提供的event消息）</param>
    /// <returns>加密后的完整回调消息（可直接POST到你的接口）</returns>
    //public string GenerateEncryptedTestMsg(string rawXml)
    //{
    //    try
    //    {
    //        // 1. 生成时间戳和随机数（模拟企业微信的请求参数）
    //        //string timestamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
    //        string timestamp = "1761025974";
    //        //string nonce = Guid.NewGuid().ToString().Substring(0, 10); // 随机字符串
    //        string nonce = "qrsyfr6c22r"; // 随机字符串

    //        // 2. 使用现有WXBizMsgCrypt类进行加密
    //        WXBizMsgCrypt crypt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
    //        string encryptedMsg = "";
    //        int result = crypt.EncryptMsg(rawXml, timestamp, nonce, ref encryptedMsg);

    //        if (result == 0)
    //        {
    //            // 加密成功，返回包含加密信息的XML（可直接作为POST请求体）
    //            return encryptedMsg;
    //        }
    //        else
    //        {
    //            throw new Exception($"加密失败，错误码：{result}");
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        Console.WriteLine($"生成加密消息失败：{ex.Message}");
    //        return null;
    //    }
    //}
}